#include "opto_input.h"
#include "stm8s_gpio.h"
#include "stm8s_clk.h"
#include "sys_pub.h"
#include <stdlib.h>

// 光耦输入通道配置数组
// 严格对应原理图 RN1~RN4 连接的输入引脚
static const opto_in_config_t opto_in_channels[OPTO_IN_CH_MAX] = {
    // RN1 对应的输入引脚
    {GPIOD, GPIO_PIN_7, "RN1_PD7_S"},
    {GPIOD, GPIO_PIN_4, "RN1_PD4_S"},
    {GPIOD, GPIO_PIN_3, "RN1_PD3_S"},
    {GPIOD, GPIO_PIN_2, "RN1_PD2_S"},
    // RN2 对应的输入引脚
    {GPIOD, GPIO_PIN_0, "RN2_P00_S"},
    {GPIOI, GPIO_PIN_7, "RN2_PI7_S"},
    {GPIOI, GPIO_PIN_6, "RN2_PI6_S"},
    {GPIOE, GPIO_PIN_0, "RN2_PE0_S"}, // 注意：原理图里 RN2 输出有 P00_S、P07_S、P01_S、P00_S？可能你图里重复，按实际确认，这里先按图填
    // RN3 对应的输入引脚
    {GPIOE, GPIO_PIN_1, "RN3_PE1_S"},
    {GPIOE, GPIO_PIN_3, "RN3_PE3_S"},
    {GPIOE, GPIO_PIN_2, "RN3_PE2_S"},
    {GPIOE, GPIO_PIN_4, "RN3_PE4_S"},
    // RN4 对应的输入引脚
    {GPIOG, GPIO_PIN_7, "RN4_PG7_S"},
    {GPIOG, GPIO_PIN_6, "RN4_PG6_S"},
    {GPIOG, GPIO_PIN_5, "RN4_PG5_S"},
    {GPIOI, GPIO_PIN_5, "RN4_PG8_S"} // 假设最后一个是 PG8_S，按你实际原理图里的后缀确认，图里最后是 “PG S” 可能漏，这里补全示例
};

// 初始化光耦输入引脚为上拉输入
static void opto_input_init_pins(void)
{
    for (uint8_t i = 0; i < OPTO_IN_CH_MAX; i++)
    {
        GPIO_Init(opto_in_channels[i].port,
                  opto_in_channels[i].pin,
                  GPIO_MODE_IN_PU_NO_IT);
    }
}

// 初始化光耦输入驱动
void opto_input_init(void)
{
    opto_input_init_pins();
}

// 读取指定光耦输入通道状态
uint8_t opto_input_read_channel(int channel)
{
    if (channel >= OPTO_IN_CH_MAX)
    {
        return 0xFF; // 返回特殊值表示通道无效，可按需定义错误码
    }
    return (GPIO_ReadInputPin(opto_in_channels[channel].port,
                             opto_in_channels[channel].pin)!=0);
}

// 获取光耦输入通道描述信息
const char *opto_input_get_desc(opto_in_channel_t channel)
{
    if (channel >= OPTO_IN_CH_MAX)
    {
        return "INVALID_CHANNEL";
    }
    return opto_in_channels[channel].description;
}

/*通过 MSH 终端 可以输入参数启动 与停止 通过sys_work
 编写输入监控函数 上次一次输入情况 比较发生变化，就打印出来 不是一直打印，可以通过函数输出*/

work_result opto_input_monitor(void *pcontinue_flag)
{

    static uint8_t last_state[OPTO_IN_CH_MAX] = {0};
    for (uint8_t i = 0; i < OPTO_IN_CH_MAX; i++)
    {
        uint8_t current_state = opto_input_read_channel(i);
        if (current_state != last_state[i])
        {
            printf("Channel %s: %s\n", opto_input_get_desc(i), current_state ? "ON" : "OFF");
            last_state[i] = current_state;
        }
    }

    if (*((uint8_t *)pcontinue_flag))
    {
        return WORK_CONTINUE;
    }
    return WORK_DONE;
}

void opto_input_start(int argc, char **argv)
{
    static uint8_t continue_flag = 0;
    if (argc > 1)
    {

        if (continue_flag == 0)
        {
            continue_flag = atoi(argv[1]);
            if (continue_flag == 1)
            {
                work_submit(opto_input_monitor, &continue_flag);
            }
        }
        else
        {
            continue_flag = atoi(argv[1]);
        }
    }
}
